{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\ntyQV6P8Dfr3xodos2HMAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10a0f0b00>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#P165 of \"Doing Math with Python\": Interactive version of drawing the Barnsley Fern\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "from ipywidgets import interact\n",
    "import ipywidgets as widgets\n",
    "\n",
    "import random\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def transformation_1(p):\n",
    "    x = p[0]\n",
    "    y = p[1]\n",
    "    x1 = 0.85*x + 0.04*y\n",
    "    y1 = -0.04*x + 0.85*y + 1.6\n",
    "    return x1, y1\n",
    "\n",
    "def transformation_2(p):\n",
    "    x = p[0]\n",
    "    y = p[1]\n",
    "    x1 = 0.2*x - 0.26*y\n",
    "    y1 = 0.23*x + 0.22*y + 1.6\n",
    "    return x1, y1\n",
    "\n",
    "def transformation_3(p):\n",
    "    x = p[0]\n",
    "    y = p[1]\n",
    "    x1 = -0.15*x + 0.28*y\n",
    "    y1 = 0.26*x  + 0.24*y + 0.44\n",
    "    return x1, y1\n",
    "\n",
    "def transformation_4(p):\n",
    "    x = p[0]\n",
    "    y = p[1]\n",
    "    x1 = 0\n",
    "    y1 = 0.16*y\n",
    "    return x1, y1\n",
    "\n",
    "def get_index(probability):\n",
    "    r = random.random()\n",
    "    c_probability = 0\n",
    "    sum_probability = []\n",
    "    for p in probability:\n",
    "        c_probability += p\n",
    "        sum_probability.append(c_probability)\n",
    "    for item, sp in enumerate(sum_probability):\n",
    "        if r <= sp:\n",
    "            return item\n",
    "    return len(probability)-1\n",
    "\n",
    "def transform(p):\n",
    "    # list of transformation functions\n",
    "    transformations = [transformation_1, transformation_2,\n",
    "                           transformation_3, transformation_4]\n",
    "    probability = [0.85, 0.07, 0.07, 0.01]\n",
    "    # pick a random transformation function and call it\n",
    "    tindex = get_index(probability)\n",
    "    t = transformations[tindex]\n",
    "    x, y = t(p)\n",
    "    return x, y\n",
    "\n",
    "def draw_fern(n):\n",
    "    # We start with (0, 0)\n",
    "    x = [0]\n",
    "    y = [0]\n",
    "    x1, y1 = 0, 0\n",
    "    for i in range(n):\n",
    "       x1, y1 = transform((x1, y1))\n",
    "       x.append(x1)\n",
    "       y.append(y1)\n",
    "    \n",
    "    # Plot the points\n",
    "    plt.plot(x, y, 'o')\n",
    "    plt.title('Fern with {0} points'.format(n))\n",
    "    plt.show()\n",
    " \n",
    "# Allow interaction via the interact() function and an Integer slider widget\n",
    "i = interact(draw_fern, n=widgets.IntSlider(min=0, max=10000,step=1,value=10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
